#!/usr/bin/env ruby
############################################################################
#    Copyright (C) 2009 by Davide Monfrecola                               #
#    davide.monfrecola@gmail.com                                           #
#                                                                          #
#    This program is free software; you can redistribute it and#or modify  #
#    it under the terms of the GNU General Public License as published by  #
#    the Free Software Foundation; either version 2 of the License, or     #
#    (at your option) any later version.                                   #
#                                                                          #
#    This program is distributed in the hope that it will be useful,       #
#    but WITHOUT ANY WARRANTY; without even the implied warranty of        #
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #
#    GNU General Public License for more details.                          #
#                                                                          #
#    You should have received a copy of the GNU General Public License     #
#    along with this program; if not, write to the                         #
#    Free Software Foundation, Inc.,                                       #
#    59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             #
############################################################################

# The module GtkGUI contains methods and costants used for the program GUI.

module Gtkgui

require 'iconv'

URL = 0; OVERLAPS = 1; SIMILARITY = 2
=begin
Add three columns to the GtkTreeView.
Columns 1: WebDocument url (string)
Columns 2: total overlaps (string)
Columns 3: similarity (integer)
=end
	def Gtkgui.setup_tree_view(treeview)
		# Create a new GtkCellRendererText, add it to the tree
		# view column and append the column to the tree view.
		renderer = Gtk::CellRendererText.new
		column = Gtk::TreeViewColumn.new("URL", renderer, "text" => URL)
		renderer.width_chars = 80																# set the number of character of the text cell
		column.resizable = true
		treeview.append_column(column)
		column = Gtk::TreeViewColumn.new("Total overlaps", Gtk::CellRendererText.new, "text" => OVERLAPS)
		column.clickable = true
		column.sort_indicator = true															# show sorting indicator
		column.sort_column_id = OVERLAPS													# set the column for sorting
		treeview.append_column(column)
		column = Gtk::TreeViewColumn.new("Similarity", Gtk::CellRendererProgress.new, "value" => SIMILARITY)
		column.set_fixed_width(300)
		column.clickable = true
		column.sort_indicator = true															# show sorting indicator
		column.sort_column_id = SIMILARITY												# set the column for sorting
		treeview.append_column(column)
	end
	
	
	class ListItem
		attr_accessor :url, :overlaps, :similarity
		def initialize(u, o, s); @url, @overlaps, @similarity = u, o, s; end
	end
	
	
	def Gtkgui.showListStore(glade, master, overlaps)
		window = Gtk::Window.new(Gtk::Window::TOPLEVEL)
		window.resizable = true
		window.title = "Results list - "+master										# window title
		window.border_width = 10
		window.window_position = Gtk::Window::POS_CENTER_ALWAYS		# window initial position

		window.signal_connect('delete_event') { window.hide; glade["mainWindow"].show }
		window.set_size_request(800, 350)													# window size

		@infoWindow = glade["infoWindow"]
		# if the window received a delete_event hide the widget and don't destroy it
		@infoWindow.signal_connect('delete_event') { @infoWindow.hide }
		
		# create a list of overlaps ListItem
		list = Array.new
		i = 0
		for item in overlaps
			tot = item.copy_doc.num_words()													# get the number of words
			n_overlaps = item.tot_words()														# get the number of overlaps
			similarity = ((n_overlaps.to_f/tot.to_f))*100.0						# calculate the similarity %
			list[i] = ListItem.new(item.copy_doc.doc_name, item.num_overlaps, similarity) # create new ListItem
			i = i +1
		end
		
		treeview = Gtk::TreeView.new
		Gtkgui.setup_tree_view(treeview)

		# Create a new tree model with three columns, as Boolean,
		# integer and string.
		store = Gtk::ListStore.new(String, Integer, Integer)
		store.set_sort_column_id(SIMILARITY, order = Gtk::SORT_DESCENDING)	# set the column for default sorting
		store.methods
				
		# Add all of the products to the GtkListStore.
		list.each_with_index do |e, i|
				iter = store.append																							# append a new row to ListStore
				# set the values
				# set_value(iter, column, value)
				store.set_value(iter, URL,   list[i].url)
				store.set_value(iter, OVERLAPS, list[i].overlaps)
				store.set_value(iter, SIMILARITY,  list[i].similarity)
		end
		
		# Add the tree model to the tree view
		treeview.model = store
		
		scrolled_win = Gtk::ScrolledWindow.new
		scrolled_win.add(treeview)
		scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
		
		treeview.signal_connect('button-press-event') do |w, e|
			treeview_clicked(w, e, overlaps, glade)
		end
		
		# show the window
		window.add(scrolled_win)
		window.show_all
	end

	def Gtkgui.createProgressBar()
		window = Gtk::Window.new(Gtk::Window::TOPLEVEL)
		window.resizable = true
		window.set_title  "Progress Bar"
		window.border_width = 10
		window.signal_connect('delete_event') { Gtk.main_quit }
		window.set_size_request(-1, -1)
		window.window_position = Gtk::Window::POS_CENTER

		align = Gtk::Alignment.new(0.5, 0.5, 0.0, 0.0)
		@pbar = Gtk::ProgressBar.new
		align.add(@pbar)


		hbox = Gtk::HBox.new(false, 5)
		hbox.border_width = 10

		hbox.pack_start(align, false, false, 5)

		window.add(hbox)
		window.show_all
		return pbar
	end
	
	def Gtkgui.process_gui_events
    while Gtk::events_pending?
      Gtk::main_iteration
    end
  end
  
  # call after a button-press-event signal
  # widget: call widget
  # event: Gdk::Event object 
  def Gtkgui.treeview_clicked(treeview, event, overlaps, glade)
  	# double click event
    if (event.button == 1) && (event.event_type == Gdk::Event::BUTTON2_PRESS)
        puts "Double clicked on treeview" 
        # open a window to diplay the information on the WebDocument
				store = treeview.model																			# get the ListStore object
				# get the selected row
				store.each do |model,path,iter| 
					
				end
				# Gets the Gtk::TreeSelection associated with the TreeView and 
				# gets the selected row
				treeview.selection.selected_each do |model,path,iter| 
					item = Gtkgui.get_copy_doc(iter[0], overlaps)							# get the Overlap object
					Gtkgui.showInfoWindow(glade, item, iter[2])
				end
    end
  end
  
  # Show the information on the document (item)
  # infoWindow: GTK window
  # item: WebDocument object
  def Gtkgui.showInfoWindow(glade, item, similarity)
  	@infoWindow.title = "Document information - #{item.copy_doc.doc_name}"
  	glade["docName"].text = "Total overlaps found: #{item.num_overlaps}"
  	glade["totOverlaps"].text = "Total common words: #{item.tot_words}"
  	glade["similarityProgress"].fraction = similarity / 100.0
  	glade["similarityProgress"].text = similarity.to_s + "%"
    @infoWindow.show
    puts "text view object created"
  	resultString = ""
    # copy document tab overlaps showing
    text_view_copy = glade["text_view_copy"]
    text_buffer = item.copy_doc.to_s
    # experimental code
    text_view_copy.buffer.text = text_buffer
    buffer = text_view_copy.buffer
    # create tag that will be applied to the overlap text
    buffer.create_tag("fg", {"background" => "yellow"})
    item.overlaps.each do |index|
      start_char = item.copy_doc.get_char_position(index[2][0])     # get the initial position in @text
      end_char = item.copy_doc.get_char_position(index[2][1])       # get the final position in @text
      start_iter = buffer.get_iter_at_offset(start_char)            # get a TextIter Object for the first character
      end_iter = buffer.get_iter_at_offset(end_char)                # get a TextIter Object for the last character
      # Apply tag
      buffer.apply_tag("fg", start_iter, end_iter)
    end
    text_view_copy.show

    # master document tab overlaps showing
    text_view_master = glade["text_view_master"]
    text_view_master.buffer.text = item.master_doc.to_s
    # experimental code
    buffer = text_view_master.buffer
    # create tag that will be applied to the overlap text
    buffer.create_tag("fg", {"background" => "yellow"})
    item.overlaps.each do |index|
      start_char = item.master_doc.get_char_position(index[1][0])     # get the initial position in @text
      end_char = item.master_doc.get_char_position(index[1][1])       # get the final position in @text
      start_iter = buffer.get_iter_at_offset(start_char)            # get a TextIter Object for the first character
      end_iter = buffer.get_iter_at_offset(end_char)                # get a TextIter Object for the last character
      #puts buffer.get_text(start_iter, end_iter)
      # Apply tag
      buffer.apply_tag("fg", start_iter, end_iter)
    end
    text_view_master.show
  end
  
  	def Gtkgui.showLocalInfoWindow(glade, item)
      # create and add the textView object
      text_view_copy = glade["text_view_copy"]
      text_view_master = glade["text_view_master"]
      infoWindow = glade["infoWindow"]
      # if the window received a delete_event hide the widget and don't destroy it
	  infoWindow.signal_connect('delete_event') { infoWindow.hide }
      tot = item.copy_doc.num_words()                               # get the number of words
      n_overlaps = item.tot_words()                                   # get the number of overlaps
      similarity = ((n_overlaps.to_f/tot.to_f))*100.0
      infoWindow.title = "Document information - #{item.copy_doc.doc_name}"
      glade["docName"].text = "Total overlaps found: #{item.num_overlaps}"
      glade["totOverlaps"].text = "Total common words: #{item.tot_words}"
      puts similarity
      glade["similarityProgress"].fraction = similarity / 100.0
      glade["similarityProgress"].text = similarity.to_s + "%"
      infoWindow.show
      # copy document tab overlaps showing
      text_view_copy.buffer.text = item.copy_doc.to_s
      # experimental code
      buffer = text_view_copy.buffer
      # create tag that will be applied to the overlap text
      buffer.create_tag("fg", {"background" => "yellow"})
      item.overlaps.each do |index|
        start_char = item.copy_doc.get_char_position(index[2][0])   		# get the initial position in @text
        end_char = item.copy_doc.get_last_char_position(index[2][1])     	# get the final position in @text
        start_iter = buffer.get_iter_at_offset(start_char)         			# get a TextIter Object for the first character
        end_iter = buffer.get_iter_at_offset(end_char)          			# get a TextIter Object for the last character
        # Apply tag
        buffer.apply_tag("fg", start_iter, end_iter)
      end
      
      	# master document tab overlaps showing
    	text_view_master.buffer.text = item.master_doc.to_s
    	# experimental code
    	buffer = text_view_master.buffer
      	# create tag that will be applied to the overlap text
      	buffer.create_tag("fg", {"background" => "yellow"})
      	item.overlaps.each do |index|
        start_char = item.master_doc.get_char_position(index[1][0])   		# get the initial position in @text
        end_char = item.master_doc.get_last_char_position(index[1][1])     	# get the final position in @text
        start_iter = buffer.get_iter_at_offset(start_char)         			# get a TextIter Object for the first character
        end_iter = buffer.get_iter_at_offset(end_char)           			# get a TextIter Object for the last character
        #puts buffer.get_text(start_iter, end_iter)
        # Apply tag
        buffer.apply_tag("fg", start_iter, end_iter)
      end
  	end
  
  # create new textView object to the scrolled window passed, and return it.
  def Gtkgui.add_textView(scrolled_win)
      textView = Gtk::TextView.new
      scrolled_win.add(textView)
      textView.visible = true
      scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS)
      textView.show
      return textView
  end

  # find a WebDocument object with the given url
  # url: WebDocument URL
  # overlaps: overlaps list
  # return an Overlap object
  def Gtkgui.get_copy_doc(url, overlaps)
  	for item in overlaps
  		if item.copy_doc.doc_name == url
  			return item
  		end
  	end
  	nil
  end

  def Gtkgui.onBrowse(widget, type)
		dialog = Gtk::FileChooserDialog.new("Open File", widget, Gtk::FileChooser::ACTION_OPEN, nil, [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL], [Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT])
		filter1 = Gtk::FileFilter.new
		filter2 = Gtk::FileFilter.new
		filter3 = Gtk::FileFilter.new
		
		filter1.name = "Text Files"
		filter2.name = "Document files"
		filter3.name = "All Files"
		
		filter1.add_pattern('*.txt')
		filter1.add_pattern('*.rb')
		filter1.add_pattern('*.c')
		filter2.add_pattern('*.pdf')
		filter2.add_pattern('*.doc')
		filter2.add_pattern('*.odt')
		filter2.add_pattern('*.html')
		filter3.add_pattern('*')
		
		dialog.add_filter(filter2)
		dialog.add_filter(filter1)
		dialog.add_filter(filter3)
		dialog.show
		if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
		filename = dialog.filename
		puts "filename = #{filename}"
		end
		dialog.destroy
		return filename
	end # onBrowse
  
  	def Gtkgui.showWarning(glade)
  		dialog = Gtk::MessageDialog.new(glade["mainWindow"], 
				                                Gtk::Dialog::MODAL,
				                                Gtk::MessageDialog::ERROR,
				                                Gtk::MessageDialog::BUTTONS_OK,
				                                "Error while creating master document, see the log file")
		dialog.run
		dialog.destroy
  	end
  
  # update the progress bar text and fraction
  	def Gtkgui.updateProgressBar(progressBar, text, fraction)
		progressBar.fraction = fraction
		progressBar.text = text
		# do this only if is called by the main thread
		if Thread.current == Thread.main
			Gtkgui.process_gui_events
		end
  	end
  	
  	def Gtkgui.searchOperationComplete(glade, overlap, totOverlaps)
      if $local == false
        glade["progressbar1"].fraction = 1.0
        glade["progressbar1"].text = "Operation complete"
        glade["infoLabel3"].text = ""                                    
        glade["showResultsButton"].sensitive = true if(overlap.nil? == false)  # only if overlap != nil
        glade["closeButton"].sensitive = true
        glade["cancelButton"].sensitive = false
        if(overlap)
          glade["infoLabel1"].text = "Total overlaps: #{totOverlaps}"
        else
          glade["infoLabel1"].text = "No overlaps found"
        end
      else
        # show the overlaps with a ListSotre widget
        # @master contains the path of the master document (string)
        # @overlaps contains the list with the overlaps found on the internet
        if(overlap)
          Gtkgui.showLocalInfoWindow(glade, overlap)
          glade["showProgress"].hide
        else
          glade["progressbar1"].fraction = 1.0
          glade["progressbar1"].text = "Operation complete"
          glade["infoLabel3"].text = ""
          glade["cancelButton"].sensitive = false
          glade["closeButton"].sensitive = true
          glade["infoLabel1"].text = "No overlaps found"
        end
      end
    end
  	
  	def Gtkgui.controlInputs(mainWindow, localButton, webButton, masterURI, copyURI)
  		if (webButton.active?)
			if (masterURI.text == "")
				dialog = Gtk::MessageDialog.new(mainWindow, 
				                                Gtk::Dialog::MODAL,
				                                Gtk::MessageDialog::WARNING,
				                                Gtk::MessageDialog::BUTTONS_OK,
				                                "You have to select a master document")
				dialog.run
				dialog.destroy
				return false
			else
				return true
			end #if
		elsif (copyURI.text == "") || (masterURI.text == "")
			dialog = Gtk::MessageDialog.new(mainWindow, 
				                                Gtk::Dialog::MODAL,
				                                Gtk::MessageDialog::WARNING,
				                                Gtk::MessageDialog::BUTTONS_OK,
				                                "You have to select a document")
			dialog.run
			dialog.destroy
			return false
		else
			return true
		end # if
  	end
end


# old code -> showing overlaps
=begin
  	i = 1
  	item.overlaps.each do |index|
			resultString = resultString +"Overlap #{i} size -> #{index[0]}\n"
			resultString = resultString + item.copy_doc.get_words(index[2][0], index[0]).to_s + "\n\n"
			i = i + 1
		end # do
  	textView.buffer.text = resultString
=end
